package list

import (
	"sieve_engine/lib/rand"
	"sort"
)

type List[T comparable] []T

func (l *List[T]) Len() int {
	return len(*l)
}

func (l *List[T]) Append(v ...T) {
	*l = append(*l, v...)
}

func (l *List[T]) RemoveAt(i int) bool {
	if i >= 0 && i < l.Len() {
		*l = append((*l)[:i], (*l)[i+1:]...)
		return true
	}
	return false
}

func (l *List[T]) Get(i int) (t T, ok bool) {
	if i >= 0 && i < l.Len() {
		t = (*l)[i]
		ok = true
	}
	return
}

func (l *List[T]) PopAt(i int) (t T, ok bool) {
	if i >= 0 && i < l.Len() {
		t = (*l)[i]
		ok = l.RemoveAt(i)
	}
	return
}

func (l *List[T]) Concat(list ...List[T]) {
	for _, v := range list {
		l.Append(v...)
	}
}

func (l *List[T]) Distinct() {
	dst := []T{}
	m := map[T]bool{}
	for _, i := range *l {
		if m[i] {
			continue
		}
		m[i] = true
		dst = append(dst, i)
	}
	*l = dst
}

func (l *List[T]) Contains(v T) bool {
	for _, r := range *l {
		if r == v {
			return true
		}
	}
	return false
}

func (l *List[T]) Count(v T) int {
	cnt := 0
	for _, r := range *l {
		if r == v {
			cnt += 1
		}
	}
	return cnt
}

func (l *List[T]) Remove(v T) bool {
	for i, r := range *l {
		if r == v {
			return l.RemoveAt(i)
		}
	}
	return false
}

func (l *List[T]) RemoveAll(v T) int {
	cnt := 0
	for i := 0; i < l.Len(); i++ {
		if (*l)[i] == v && l.RemoveAt(i) {
			cnt++
			i--
		}
	}
	return cnt
}

// Shuffle 打乱数组
func (l *List[T]) Shuffle() {
	for i := l.Len() - 1; i > 0; i-- {
		j := rand.Lt(i + 1)
		(*l)[i], (*l)[j] = (*l)[j], (*l)[i]
	}
}

// Sort 排序数组
func (l *List[T]) Sort(f func(T, T) bool) {
	sort.Slice(*l, func(i, j int) bool {
		return f((*l)[i], (*l)[j])
	})
}

// Reverse 反转数组
func (l *List[T]) Reverse() {
	i := 0
	j := l.Len() - 1
	for i < j {
		(*l)[i], (*l)[j] = (*l)[j], (*l)[i]
		i++
		j--
	}
}

// Map 迭代并替换数组的值
func (l *List[T]) Map(fn func(T) T) {
	for i, v := range *l {
		(*l)[i] = fn(v)
	}
}

// Func 函数式方法，不影响原数组，链式调用
func (l *List[T]) Func() *Func[T] { return &Func[T]{*l} }

type Func[T comparable] struct {
	l List[T]
}

func (f *Func[T]) ToList() List[T] { return f.l }

func (f *Func[T]) Clone() *Func[T] {
	nf := &Func[T]{l: make(List[T], f.l.Len())}
	copy(nf.l, f.l)
	return nf
}

// Every 检查是否每一项都满足条件
func (f *Func[T]) Every(fn func(T) bool) bool {
	for _, v := range f.l {
		if !fn(v) {
			return false
		}
	}
	return true
}

// Any 检查任意一项满足条件
func (f *Func[T]) Any(fn func(T) bool) bool {
	for _, v := range f.l {
		if fn(v) {
			return true
		}
	}
	return false
}

// ForEach 遍历
func (f *Func[T]) ForEach(fn func(T)) *Func[T] {
	for _, v := range f.l {
		fn(v)
	}
	return f
}

// Where 返回所有满足条件元素的新数组
func (f *Func[T]) Where(fn func(T) bool) *Func[T] {
	nf := &Func[T]{l: List[T]{}}
	for _, v := range f.l {
		if fn(v) {
			nf.l.Append(v)
		}
	}
	return nf
}

// Shuffle 返回一个新的数组并打乱
func (f *Func[T]) Shuffle() *Func[T] {
	l := f.Clone().ToList()
	l.Shuffle()
	return l.Func()
}

// Sort 返回一个新的数组并排序
func (f *Func[T]) Sort(fn func(T, T) bool) *Func[T] {
	l := f.Clone().ToList()
	l.Sort(fn)
	return l.Func()
}

// Reverse 返回一个新的数组并反转
func (f *Func[T]) Reverse() *Func[T] {
	l := f.Clone().ToList()
	l.Reverse()
	return l.Func()
}

// Map 返回一个新的数组并迭代替换
func (f *Func[T]) Map(fn func(T) T) *Func[T] {
	l := f.Clone().ToList()
	l.Map(fn)
	return l.Func()
}

// Reduce 迭代数组并将数组减少为单值
func (f *Func[T]) Reduce(fn func(T, T) T) (t T) {
	if f.l.Len() > 0 {
		t = f.l[0]
		for i := 1; i < f.l.Len(); i++ {
			t = fn(t, f.l[i])
		}
	}
	return
}

func (f *Func[T]) Concat(list ...List[T]) *Func[T] {
	l := f.Clone().ToList()
	l.Concat(list...)
	return l.Func()
}

func (f *Func[T]) Distinct() *Func[T] {
	l := f.Clone().ToList()
	l.Distinct()
	return l.Func()
}
